(function ($) {
jQuery.fn.extend({
lookup_report: function(options, _callback){
	var defaults = {
			  width				: 640
			, height			: 480
			, title				: "Form Report"
			, type				: null //OPTIONS: null - show everything; create - show create screen; edit - show edit screen
			, context			: null
			, eventName			: "click"
			, data				: []
			, data_dropdown		: _build_data_dropdown
			, field				: _form_get_field
			, number_dropdown	: _build_number_dropdown
			, content_area		: null
			, _callback			: null
			, ui_groups			: []
			, link_buttons		: []
		};

	var table = null;

	options = $.extend(true, {}, defaults, options);

	if (_callback) options._callback = _callback;

	if (options.eventName && options.eventName != null){
		$(this).unbind(options.eventName).bind(options.eventName, function(){show();});
	} else {
		show();
	}

	function show(){
		switch(options.type){
			case "create":
				_create_new_dlg();
				break;
			default:
				_create_with_data_grid();
				break;

		}
	}

	function _create_form_input(field, with_primary_key){
		if (typeof field.show_on_editor !== "undefined"){
			if (field.show_on_editor == false) return "";
		}

		if (field.primary_key == true){
			if (with_primary_key == undefined || with_primary_key == false)
				return "";
		}
		name = field.name;
		if (typeof field.alias !== "undefined" && $.trim(field.alias) != "" && field.alias != null){
			name = field.alias;
		}
		
		var result = "<label for='"+name+"'>"+field.title+"</label>"
		var float_left = "margin-top:1em;margin-bottom;1em;";
		if (options.alignment == "horizontal"){
			float_left += "float:left;width:45%;margin:5px;";
			result = "<div class='label'>"+field.title+"</div>";
		}
		
		var data_type = $.trim(field.data_type).toLowerCase();

		if (data_type == "date" || data_type == "datetime")
			result += "<input type='text' id='"+name+"' class='form_data widget-datepicker' />";
		else if (data_type == "boolean")
			result += "<input type='checkbox' id='"+name+"' class='form_data ui-widget' />";
		else if (data_type == "number")
			result += "<input type='number' id='"+name+"' class='form_data ui-widget' />";
		else if (data_type == "color"){
			result += "<p id='"+name+"' class='form_data widget-colorpicker'></p>";
		}
		else if (data_type == "lookup")
			result += "<select id='"+name+"' class='form_data select ui-widget' />";
		else if (data_type == "notes")
			result += "<textarea id='"+name+"' class='form_data ui-widget' style='width:250px;height:80px;'></textarea>";
		else if (data_type == "password")
			result += "<input type='password' id='"+name+"' class='form_data ui-widget' />";
		else
			result += "<input type='text' id='"+name+"' class='form_data ui-widget' />";

		result = "<div style='"+float_left+"' >"+result+"</div>";
		
		return result;
	}

	function _get_grid_field_value(field, value){
		var result = value;

		switch(field.data_type){
			case "boolean":
				result = (value == 1 ? "Y" : "");
				break;
		}

		if (typeof options.ajax_url === "undefined" || options.ajax_url == null || $.trim(options.ajax_url) == ""){
			if (field.data_type == "lookup"){
				//WITH NO URL, IT MEANS WE NEED TO TRANSLATE THE SELECTED ID INTO A NAME
				var fk = field.foreign_key;
				if (fk){ //JUST IN-CASE THE FOREIGN KEY WAS NOT SET
					if (fk.sql_table in cache){
						var data = cache[fk.sql_table];
						$(data).each(function(){
							if ((fk.value in this) && (this[fk.key] == value)){
								result = this[fk.value];
							}
						});
					}
				}
			}
		}
		
		if (result) result = result.replace(/(\n)/g,"<br/>");
		
		return result;
	}

	function _crud_init_dialog(context){
		//NOW DO THE FOREIGN-KEY FIELDS
		$(options.fields).each(function(){
			if (this.foreign_key){
				_build_foreign_key(context, this);
			}

			if (this.readonly && this.readonly == true){
				if (this.data_type != "lookup"){
					context.find("#"+this.name).attr("readonly", "readonly");
				}
				else{
					context.find("#"+this.name).attr("disabled", "disabled");
				}
			}

			var value = _get_field_default_value(this);
			if (this.data_type == "boolean"){
				if (parseFloat(value) == 1 || value === true)
					context.find("#"+this.name).prop("checked", true);
			}
			else if (this.data_type != "lookup")
				context.find("#"+this.name).val(value);
		});
	}

	function _get_field_default_value(field){
		value = null;
		if (field.name == "group"){
			field.default_value = "system.group";
		}

		if (field.default_value){
			switch(field.default_value){
				case "system.user":
					value = user_credentials.id;
					break;
				case "system.date":
					value = $.format.date(new Date(), "yyyy-MM-dd HH:mm:ss");
					break;
				case "system.group":
					value = cache.subscription;
					break;
				default:
					value = field.default_value;
			}
		}

		if (value) value = value.replace(/(\n)/g,"<br/>");
		
		return value;
	}

	function _format_date_fields(context){
		context.find(".widget-datepicker").not(".hasDatePicker").datepicker({dateFormat:"yy-mm-dd"});
		context.find(".widget-colorpicker").each(function(){
			obj = $(this);
			$(this).ColorPicker({
				eventName: "click"
				, color: obj.val()
				, livePreview: true
				, flat: true
				, onSubmit: function(hsb, hex, rgb, el) {
					$(el).val("#"+hex);
					$(el).ColorPickerHide();
				}
				, onBeforeShow: function () {
				}
				, onChange:  function (hsb, hex, rgb) {
					obj.val("#"+hex);
				}
			})
		});
	}

	function _build_foreign_key(context, field){
		//VERY CUSTOM CODE :-(
		if (field.name == "group_id" && typeof field.default_value == "undefined") field.default_value = "system.group";
		//END OF VERY CUSTOM CODE :-)

		if (typeof field.default_value == "undefined") field.default_value = null;

		function __build_select(field, data){
			if (typeof field.sort_order !== "undefined"){
				if ($.trim(field.sort_order.toLowerCase()) == "asc"){
					data.sort(function(a,b){
						//console.log("comparing: "+a[field.foreign_key.value]+ " ==> "+ b[field.foreign_key.value]);
						return a[field.foreign_key.value].localeCompare(b[field.foreign_key.value]);
					});
				} else if ($.trim(field.sort_order.toLowerCase()) == "desc"){
					data.sort(function(a,b){
						return b[field.foreign_key.value].localeCompare(a[field.foreign_key.value]);
					});
				}
			}
			
			select_field = context.find("#"+field.name);
			select_field.append("<option>");
			$(data).each(function(){
				selected = "";
				if (field.default_value){
					value = _get_field_default_value(field);
					if (this[field.foreign_key.key] == value)
						selected = "selected";
				}
				select_field.append("<option "+
								selected +
								" value='"+
								this[field.foreign_key.key]+
								"'>"+
								this[field.foreign_key.value]+
								"</option>");
			});
		}

		var skip_ajax = false;
		if (field.foreign_key.sql_table in cache){
			data = cache[field.foreign_key.sql_table];
			skip_ajax = true;
		} else {
			switch(field.default_value){
				case "system.group":
					//FIRST CHECK IF THE SELECTED SUBSCRIPTION IS IN THE CACHE
					var found = false;
					$(cache.client_list).each(function(){
						if (this.id == cache.defualt_client) found = true;
					});
					if (true == found){
						data = cache.client_list;
						skip_ajax = true;
					}
					break;
			}
		}

		if (false == skip_ajax && options.ajax_url && options.ajax_url != null){
			fk_fields = [
					  {name: field.foreign_key.key}
					, {name: field.foreign_key.value}
				];
			request = {
				  sql_table		: field.foreign_key.sql_table
				, ajax_url		: "lookup_tables.php"//options.ajax_url
				, fields		: fk_fields
				, server_call	: "lookup_read"//options.server_call_list
				};

			get_server_data(request, function(data){
				__build_select(field, data);
			});
		}
		else
			__build_select(field, data);
	}

	function _format_table(table){
		table = $(table);
		if (table.hasClass("has-stripes"))
			table.find("tbody tr:odd").addClass("table-stripe");

		var thead = table.children("thead");
		if (thead){
			thead.addClass("ui-widget ui-widget-header");
		}
		var tbody = table.children("tbody");
		if (tbody){
			tbody.addClass("ui-widget");
		}

		tbody.find("tr")
			.hover(
				function(){
					$(this).addClass("ui-state-hover");
					$(this).css("cursor", "pointer");
				}
				, function(){
					$(this).removeClass("ui-state-hover");

					$(this).css("cursor", "default");
				}
			);
	}

	function _build_ui_groups(){
		var main_ui_group = $('<div style="display:inline-block;width:100%">');
		if (typeof options.ui_groups === "undefined")
			options.ui_groups = [];
		
		$(options.fields).each(function(){
			var field = this;
			var found = false;
			$(options.ui_groups).each(function(){
				if (this.name == field.ui_group)
					found = true;
			});
			if (false == found && (typeof field.ui_group !== "undefined"))
				options.ui_groups.push({"name":field.ui_group});
		});
		
		$(options.ui_groups).each(function(){
			var caption = this.name
			if (this.name == "__MAIN__") caption = "";
			var grp_id = this.name.replace(/ /g, "_");
			var grp_ui = $('<div style="display:inline-block;width:100%;" id="'+grp_id+'" class="ui-panel widget-container">').appendTo(main_ui_group);
			var hdr = $('<div>').html(caption).appendTo(grp_ui);
			if (caption != "")
				hdr.addClass("widget-header");

			if (caption != "")
				grp_ui.addClass("ui-border-all");

			var content = $('<div class="fieldset" style="padding-bottom:5px;">').appendTo(grp_ui);
		});

		return main_ui_group;
	}

	function _create_form(){
		var _dlg_fieldset = "";
		var ui_group = _build_ui_groups();
		options.filter = [];
		$(options.form_report.filter).each(function(index, filter){
			var field = null;
			$(options.fields).each(function(){
				if (this.name == filter)
					field = this;
			});
			
			if (field == null) return;
			options.filter.push(field);
			
			if (typeof field.ui_group !== "undefined"){
				
				var grp_id = field.ui_group.replace(/ /g, "_");
				ui_group.find("#"+grp_id+" .fieldset").append(_create_form_input(field));
			} else {
				ui_group.append(_create_form_input(field));
			}
		});
		
		ui_group.find(".ui-panel").each(function(){
			var div = $(this).find(".fieldset");
			if (div.children().length == 0){
				$(this).hide();
			}
		});
		
		return ui_group;
	}

	function _create_new_dlg(){
		console.log("filter:");
		if (typeof options.form_report.filter == "undefined" || options.form_report.filter.length == 0){
			_generate_report([]);
			return;
		}
		
		var ui_group = _create_form();

		_dlg = $("<div title='"+options.title+" - Report'>");
		_dlg.append(ui_group);

		_dlg.dialog({
			  autoOpen		: false
			, width			: options.width
			, height		: options.height
			, modal			: true
			, allFields		: []
			, open			:function(event, ui){
				_dlg.find(".form_data").children().each(function(){
					$(this).val("");
				});
				
				_crud_init_dialog(_dlg);

				_format_date_fields(_dlg);
			}
			, buttons: {
				  "Create": function(){
						data = {};
						$(options.filter).each(function(){
							if (typeof this.default_value !== "undefined"){
								data[name] = _get_field_default_value(this);
							} else {
								data[name] = null;
							}
						});

						_dlg.find(".form_data").each(function(){
							if (this.type == "checkbox")
								data[this.id] = ($(this).is(":checked") ? 1 : 0);
							else
								data[this.id] = $(this).val();
						});
						
						_dlg.dialog("close");
						_generate_report(data);
					}
				}
			, close: function() {
				_dlg.find(".widget-datepicker").datepicker("destroy").remove();
				_dlg.find(".fieldset").children().remove();
				_dlg.dialog("destroy");

				if (options.type == "create" && options._callback) options._callback(options.data);
			}

		});

		_dlg.dialog("open");
	}

	function _generate_report(filter_data){
		console.log("generate report");
		//console.log(filter_data);
		var _dlg = null;
		if (options.content_area){
			_dlg = $(options.content_area);
			_dlg.children().remove();
		} else {
			_dlg =  $("<div class='widget-content' title='"+options.title+"'></div>");
			//DIALOG OPTIONS
			_dlg.dialog({
				  autoOpen		: false
				, height		: 740 //(options.height ? options.height : 768)
				, width			: 1200 //(options.width ? options.width : 1024)
				, modal			: true
				, open			: function(event, ui){}
				, close: function() {
					if (options._callback) options._callback(options.data);
				}
			});
		}
		
		var $toolbar = $('<div class="ui-widget-header" style="width:100%;vertical-align:middle;display:inline-block;">').appendTo(_dlg);

		$toolbar.append('<div id="tb_buttonset" style="float:left">\
					<button id="btn_export" data-icon="ui-icon-arrowreturnthick-1-n">Export</button>\
				</div>');
		$toolbar.find("#tb_buttonset button").each(function(){
			$(this).css({"border":"none"}).button({
				  text: false
				, icons:{primary:$(this).attr("data-icon")}
			});
		});
		
		$toolbar.find("#btn_export").unbind("click").click(function(){
			var text = _dlg.find("table").html();
			
			var $dlg = $("<div title='XML Data'>");
			$dlg.dialog({ autoOpen: false,width: 640,height: 400,modal: true,resizable: true,draggable: true });
			var $txt = $("<textarea style='width:100%;height:99%'>").appendTo($dlg);
			$txt.val("<table>"+text+"</table>");
			$dlg.dialog("open");
		});
		
		
		
		var _build_report_header = function(){
			var container = $('<div class="widget-container">\
						<div class="widget-header">Filter Selection</div>\
						<div class="widget-content" />\
					</div>'
				);
			
			var content = container.find(".widget-content");
			for(var key in filter_data){
				if (filter_data[key] == "") continue;
				
				var p = $("<p><label></label></p>");
				
				$(options.fields).each(function(){
					if (this.name == key){
						p.find("label").html(this.title);
						
						p.append(_get_grid_field_value(this, filter_data[key]));
					}
				});
				
				content.append(p);
			}
			
			return container;
		};
		
		var __build_data_table = function(data){
			var container = $('<div class="widget-container">\
						<div class="widget-header"></div>\
						<div class="widget-content" />\
					</div>'
				);
			
			var table = $("<table border=0 style='width:100%;' class='has-stripes'>");//.appendTo(_dlg);
			
			var tr = $("<tr>").addClass("ui-widget-header");
			
			var group_by = $.trim(options.form_report.group_by);
			
			container.find(".widget-content").append(table);
			
			table.append($("<thead>").append(tr));
			$(options.form_report.fields).each(function(){
				//FIRST MAKE SURE THE FIELD IS NOT IN THE LIST SO THAT WE DO NOT SHOW IT.
				for(var key in filter_data){
					if (filter_data[key] == "") continue;
					
					if (key == this.field) return; //THIS RETURN STATEMENT ENSURES WE DON'T GET TO CREATE THE CELL.
				}

				var th = $("<th>").html(this.caption).appendTo(tr);
			});

			var tbody = $("<tbody>");
			table.append(tbody);
			
			$(data).each(function(){
				var row = this;
				
				var tr = $("<tr style='text-align:center;'>")
							.appendTo(tbody);

				
				$(options.form_report.fields).each(function(){
					var field = null;
					var table = this.table;
					var item = this;
					
					//NEED IT HERE TO MAKE SURE I SET THE PANEL HEADER
					$(options.fields).each(function(){
						if (this.name == group_by){
							container.find(".widget-header").html(_get_grid_field_value(this, row[group_by]));
						}

						if (this.name == item.field){
							field = this;
						}
					});
					
					//FIRST MAKE SURE THE FIELD IS NOT IN THE LIST SO THAT WE DO NOT SHOW IT.
					for(var key in filter_data){
						if (filter_data[key] == "") continue;
						
						if (key == this.field) return; //THIS RETURN STATEMENT ENSURES WE DON'T GET TO CREATE THE CELL.
					}
					
					var td = $("<td>")
								.css({"max-width":"200px", "word-wrap":"wrap","padding":"0.1em"})
								.appendTo(tr);

					//EVALUATE ROW-CELL VALUE
					var value = null;
					//console.log("TABLE COMPARISON: "+item.table+" == "+options.sql_table);
					if (item.table == options.sql_table){
						if (field == null) return;

						var name = field.name;
						if (typeof field.alias !== "undefined") name = field.alias;

						value = _get_grid_field_value(field, row[name]);
					
					} else {
						//NOW IF THERE IS LINKS WE SHOULD TRY TO FIND THE FOREIGN TABLE
						var fk_table = null;
						//console.log("LINKS:");
						//console.log(options.links);
						$(options.links).each(function(){
							if (this.sql_table == item.table)
								fk_table = this.reference;
						});
						
						if (fk_table != null){
							$(fk_table.fields).each(function(){
								if (this.name == item.field)
									field = this;
							});
						}
						
						//console.log("foreign table");
						if (typeof cache[item.table] !== "undefined"){
							//FIRST GO FIND A FIELD WITH THE FOREIGN KEY TO THIS TABLE
							var fk_field = null;
							$(options.fields).each(function(){
								if ((typeof this.foreign_key !== "undefined") && this.foreign_key.sql_table == item.table){
									fk_field = this;
								}
							});
							
							if (fk_field != null){
								//console.log("Find the foreign data-value");
								//console.log(fk_field);
								//console.log(item.table+" == "+fk_field.foreign_key.sql_table);
								//NOW LOCATE THE ROW IN THE FK-TABLE WHERE THE LINKED FIELDS MATCH
								$(cache[fk_field.foreign_key.sql_table]).each(function(){
									if (row[fk_field.name] == this[fk_field.foreign_key.key])
										value = _get_grid_field_value({}, this[item.field]);
								});
							}
						}
					}
					if (typeof value === "undefined") value = "";
					
					td.html("<pre class='ui-widget'>"+value+"</pre>");
					
					if (item.css_style && $.trim(item.css_style) != ""){
						td.attr("style", td.attr("style")+";"+item.css_style);
					}

				});
			});

			_format_table(table);
			table.tablesorter();
			return container;
		}
		
		var _build_report = function(data){
			var group_by = $.trim(options.form_report.group_by);
			
			_dlg.append(_build_report_header());
			
			if (data.length > 0 && group_by !== null && group_by != ""){
				data.sort(function(a, b){
					return a[group_by].localeCompare(b[group_by]);
				});
				
				var dta = [];
				var grp = data[0][group_by];
				$(data).each(function(){
					if (this[group_by] != grp){
						_dlg.append(__build_data_table(dta));
						
						dta = [];
						grp = this[group_by];
					}
					
					dta.push(this);
				});
				
				if (dta.length != 0){
					_dlg.append(__build_data_table(dta));
				}
				
			} else {
				_dlg.append(__build_data_table(data));
			}
		};
		
		//DO AN AJAX CALL TO GET FRESHEST DATA
		if ((typeof options.ajax_url !== "undefined") && options.ajax_url != null && (typeof options.server_call_list !== "undefined" && options.server_call_list != null)){
			request = {
					  ajax_url		: options.ajax_url
					, server_call	: options.server_call_list
					, sql_table		: options.sql_table
					, fields		: options.fields
					//, async			: false
				};
			request = $.extend(true, {}, options, request);
			get_server_data(request, function(data){
				_build_report(data);
			});
		} else {
			var data = [];

			//DO THE LOCAL FILTER
			$(options.data).each(function(){
				var row = this;
				var can_show = true;
				
				for(var filter in filter_data){
					if (filter_data[filter] == null || $.trim(filter_data[filter]) == "" ) continue;

					if (row[filter] != filter_data[filter]){
						can_show = false;
					}
				}
				
				if (true == can_show){
					data.push(this);
				}
			});
			
			_build_report(data);
			
		}

		if (!options.content_area){
			_dlg.dialog("open");
		}
	}

}
});
})(jQuery);
